using System;
using System.Collections.Generic;
using System.Windows.Forms;

using Elev.Core;
using Elev.UI.Controls;

namespace Elev.UI
{
    public delegate void GetStudentsFinishedEventHandler(object sender);

    public class GetStudentsCommand : ICommand
    {
        public event GetStudentsFinishedEventHandler GetStudentsFinished;
        
        GetStudentsCommandDelegate invokeMe;
        IStudentsListManager studentsList;

        // Delegate used to retreive tags asynchronously
        delegate List<Student> GetStudentsCommandDelegate();

        public GetStudentsCommand(IStudentsListManager List)
        {
            studentsList = List;

            StudentsFactory factory = new StudentsFactory();
            invokeMe = new GetStudentsCommandDelegate(factory.GetStudents);
        }

        protected virtual void OnGetStudentsFinished()
        {
            GetStudentsFinished(this);
        }

        void Callback(IAsyncResult ar)
        {
            // get the dataset as output
            List<Student> students = new List<Student>();
            try
            {
                students = invokeMe.EndInvoke(ar);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // update the grid a thread safe fasion!
            MethodInvoker updateList = delegate
            {
                try
                {
                    studentsList.BeginUpdate();
                    studentsList.Clear();
                    
                    foreach (Student student in students)
                        studentsList.Add(student);
                    
                    studentsList.EndUpdate();

                    // Set student selection
                    int intialSelectedStudent = MetaInfo.SelectedStudent;
                    if (intialSelectedStudent < studentsList.Count)
                        studentsList.SelectedStudent = intialSelectedStudent;
                    else
                        studentsList.SelectedStudent = 0;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            };

            if (studentsList.InvokeRequired)
            {
                studentsList.Invoke(updateList);
            }
            else
            {
                updateList();
            }

            if (GetStudentsFinished != null)
                OnGetStudentsFinished();
        }

        #region ICommand Members

        public void Execute()
        {
            invokeMe.BeginInvoke(this.Callback, null);
        }

        #endregion
    }
}